package com.api.user.service.impl;

import com.api.common.JSONUtils;
import com.api.common.mybatis.ResultMap;
import com.api.core.response.Result;
import com.api.core.response.ResultGenerator;
import com.api.core.service.AbstractService;
import com.api.user.dao.*;
import com.api.user.model.*;
import com.api.user.service.*;
import com.api.user.vo.CompanionVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wanghuiwen on 2021/04/02.
 */
@Service
@Transactional
public class CompanionServiceImpl extends AbstractService<Companion> implements CompanionService {
    @Resource
    private CompanionMapper companionMapper;

    @Resource
    private CompanionGameService companionGameService;

    @Resource
    private CompanionGameMapper companionGameMapper;

    @Resource
    private DisplayAreaService displayAreaService;

    @Resource
    private CompanionExamineLogService companionExamineLogService;

    @Resource
    private UserFollowMapper userFollowMapper;

    @Resource
    private UserInfoService userInfoService;
    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private CompanionOrderService companionOrderService;

    @Resource
    private CompanionOrderMapper companionOrderMapper;

    @Resource
    private CompanionReviewService companionReviewService;

    @Resource
    private CompanionReviewMapper companionReviewMapper;

    @Resource
    private CompanionOrderTrackService companionOrderTrackService;

    @Resource
    private CoinTransactionService coinTransactionService;

    @Override
    public Result list(Map<String, Object> params,String order, Integer page, Integer size){
//        Map<String, Object> params = JSONUtils.json2map(search);
        Map<String, Object> orderParams = JSONUtils.json2map(order);
        for (String key : orderParams.keySet()) {
                if (orderParams.get(key) != null && orderParams.get(key).equals("ascending")) orderParams.put(key, "asc");
                if (orderParams.get(key) != null && orderParams.get(key).equals("descending")) orderParams.put(key, "desc");
            }
        PageHelper.startPage(page, size);
        orderParams.put("companion_id","desc");
        List<CompanionVo> res = companionMapper.list(params, orderParams);
        PageInfo<CompanionVo> pageInfo = new PageInfo<>(res);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @Override
    public Result userList(Map<String, Object> params,String order, Integer page, Integer size){
//        Map<String, Object> params = JSONUtils.json2map(search);
        Map<String, Object> orderParams = JSONUtils.json2map(order);
        for (String key : orderParams.keySet()) {
                if (orderParams.get(key) != null && orderParams.get(key).equals("ascending")) orderParams.put(key, "asc");
                if (orderParams.get(key) != null && orderParams.get(key).equals("descending")) orderParams.put(key, "desc");
            }
        PageHelper.startPage(page, size);
        orderParams.put("companion_id","desc");
        params.put("userList","userList");
        params.put("service",true);
        params.put("isBan",0);
        List<CompanionVo> res = companionMapper.list(params, orderParams);
        for(CompanionVo map :res ){
            UserFollow follow = userFollowMapper.findByUserIdAndFansId(map.getUserId(), (Long) params.get("loginId"));
            if(null != follow){
                map.setFollow(true);
            }else{
                map.setFollow(false);
            }
        }
        PageInfo<CompanionVo> pageInfo = new PageInfo<>(res);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @Override
    public Result orderListUser(Map<String, Object> params, String order, Integer page, Integer size) {
        Map<String, Object> orderParams = JSONUtils.json2map(order);
        for (String key : orderParams.keySet()) {
            if (orderParams.get(key) != null && orderParams.get(key).equals("ascending")) orderParams.put(key, "asc");
            if (orderParams.get(key) != null && orderParams.get(key).equals("descending")) orderParams.put(key, "desc");
        }
        PageHelper.startPage(page, size);
        orderParams.put("order_id","desc");
        List<Map<String, Object>> res = companionOrderMapper.orderList(params, orderParams);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(res);
        Map<String,Object> result = new HashMap<>();
        result.put("list",pageInfo);
        result.put("orderCount",pageInfo.getTotal());
        result.put("amount",companionOrderMapper.orderCountAmount(params,orderParams));
        result.put("complete",companionOrderMapper.orderCountState(params,4));
        result.put("upcoming",companionOrderMapper.orderCountState(params,1));

        if(params.get("companionId")!=null){
            Companion companion =  companionMapper.selectByPrimaryKey(params.get("companionId"));
            result.put("popularity",companion.getPopularity());
        }
        return ResultGenerator.genSuccessResult(result);
    }

    @Override
    public Result reviewList(Map<String, Object> params, String order, Integer page, Integer size) {
        Map<String, Object> orderParams = JSONUtils.json2map(order);
        for (String key : orderParams.keySet()) {
            if (orderParams.get(key) != null && orderParams.get(key).equals("ascending")) orderParams.put(key, "asc");
            if (orderParams.get(key) != null && orderParams.get(key).equals("descending")) orderParams.put(key, "desc");
        }
        PageHelper.startPage(page, size);
        orderParams.put("review_id","desc");
        List<Map<String, Object>> res = companionReviewMapper.reviewList(params, orderParams);

        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(res);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @Override
    public Result apply(CompanionGame companionGame) {

        //根据用户id和游戏id，查询有没有陪玩信息
        CompanionGame companionGame1 = companionGameService.getByUserIdAndGameId(companionGame.getCompanionId(),companionGame.getGameId());
        if(companionGame1!= null){
            return ResultGenerator.genFailResult(400,"You have registered");
        }
        //查询陪玩热度
        Companion companion = this.findById(companionGame.getCompanionId());
        if(null == companion){
            companion = new Companion();
            companion.setCompanionId(companionGame.getCompanionId());
            companion.setPopularity(1);
            this.save(companion);
        }else{
            companion.setPopularity(companion.getPopularity()+1);
            this.update(companion);
        }

        companionGame.setCreateTime(new Date().getTime());
        companionGame.setExamine(1);
        companionGameService.save(companionGame);

        CompanionExamineLog companionExamineLog = new CompanionExamineLog();
        companionExamineLog.setUserId(companionGame.getCompanionId());
        companionExamineLog.setCompanionId(companionGame.getCompanionGameId());
        companionExamineLog.setCreateDate(new Date().getTime());
        companionExamineLog.setExamine(1);
        companionExamineLog.setGameNickname(companionGame.getGameNickname());
        companionExamineLog.setGameId(companionGame.getGameId());
        companionExamineLog.setIntroduction(companionGame.getIntroduction());
        companionExamineLog.setRole(companionGame.getRole());
        companionExamineLog.setStrength(companionGame.getStrength());
        companionExamineLog.setSoundUrl(companionGame.getSoundUrl());
        companionExamineLogService.save(companionExamineLog);

        return ResultGenerator.genSuccessResult();

    }

    @Override
    public Result statistics(Map<String, Object> params) {
        Map<Object, Object> result = new HashMap<>();
        if(null!=params.get("state") && ""!=params.get("state")){
            Integer count = companionOrderMapper.getCount(params);
            result.put(params.get("state").toString(),count);
        }else{
            for (int i=1;i<=5;i++){
                params.put("state",i);
                Integer count = companionOrderMapper.getCount(params);
                result.put(params.get("state"),count);
            }

        }
        return ResultGenerator.genSuccessResult(result);
    }

    @Override
    public Result perfect(CompanionPerfect companionPerfect) {
        CompanionGame companionGame = companionGameService.findById(companionPerfect.getCompanionGameId());
        companionGame.setGameNickname(companionPerfect.getGameNickname());
        companionGame.setSoundUrl(companionPerfect.getSoundUrl());
        companionGame.setIntroduction(companionPerfect.getIntroduction());
        companionGame.setStrength(companionPerfect.getStrength());
        companionGame.setRole(companionPerfect.getRole());
        companionGame.setType(companionPerfect.getType());
        companionGame.setPrice(companionPerfect.getPrice());
        companionGame.setPrice(companionPerfect.getPrice());
        companionGame.setStartTime(companionPerfect.getStartTime());
        companionGame.setEndTime(companionPerfect.getEndTime());
        companionGame.setNote(companionPerfect.getNote());
        companionGame.setPriceUnit(companionPerfect.getPriceUnit());
        companionGame.setInGameId(companionPerfect.getInGameId());
        companionGame.setService(companionPerfect.getService());


        companionGameService.update(companionGame);
        if(companionPerfect.getDisplayArea()!=null){

        String [] displayAreas = companionPerfect.getDisplayArea().split(",");
            if(displayAreas.length>0){
                List<DisplayArea> displayAreas1 = displayAreaService.getByCompanionGameId(companionPerfect.getCompanionGameId());
                if(!displayAreas1.isEmpty()){
                    for(DisplayArea displayArea:displayAreas1){
                        displayAreaService.deleteById(displayArea);
                    }
                }
            }
            for (String area : displayAreas) {
                DisplayArea displayArea = new DisplayArea();
                displayArea.setCompanionGameId(companionPerfect.getCompanionGameId());
                displayArea.setUrl(area);
                displayAreaService.save(displayArea);
            }
        }

        return ResultGenerator.genSuccessResult();
    }

    @Override
    public Result examine(Long companionId, String reason, Integer examine) {
        CompanionGame companionGame = companionGameService.findById(companionId);
        companionGame.setExamine(examine);
        companionGameService.update(companionGame);

        CompanionExamineLog companionExamineLog = companionExamineLogService.findBy("companionId",companionId);
        companionExamineLog.setExamine(examine);
        companionExamineLog.setReason(reason);
        companionExamineLogService.update(companionExamineLog);
        return ResultGenerator.genSuccessResult();
    }

    @Override
    public Result buy(Long userId,Long companionGameId, Integer hours, Long startTime) {


        CompanionGame companionGame = companionGameService.findById(companionGameId);
        BigDecimal totalAmount = companionGame.getPrice().multiply(new BigDecimal(hours));
        //判断购买用户的余额够不够
        UserInfo userInfo = userInfoService.findById(userId);
        if(userInfo.getCoin().compareTo(totalAmount) < 0){
            return ResultGenerator.genFailResult(400,"Insufficient balance");
        }

        CompanionOrder companionOrder = new CompanionOrder();
        companionOrder.setCompanionGameId(companionGameId);
        companionOrder.setCreateTime(new Date().getTime());
        companionOrder.setHours(hours);
        companionOrder.setStartDate(startTime);
        companionOrder.setTotalAmount(totalAmount);
        companionOrder.setPayMethod("coin");
        companionOrder.setUserId(userId);
        companionOrder.setState(1);
        companionOrderService.save(companionOrder);



        CoinTransaction coinTransaction = new CoinTransaction();
        coinTransaction.setOrderId(companionOrder.getOrderId());
        coinTransaction.setAmountBalance(totalAmount.negate());
        coinTransaction.setFromUserId(userId);
        coinTransaction.setTransactionType(6);
        coinTransaction.setRemark("Companion Order");
        coinTransaction.setTransactionTime(new Date().getTime());
        coinTransaction.setCreateId(userId);
        coinTransactionService.addOrSub(coinTransaction);


        CompanionOrderTrack companionOrderTrack = new CompanionOrderTrack();
        companionOrderTrack.setCreateTime(new Date().getTime());
        companionOrderTrack.setOrderId(companionOrder.getOrderId());
        companionOrderTrack.setTrackDesc("下单");
        companionOrderTrack.setUserId(userId);
        companionOrderTrackService.save(companionOrderTrack);

        return ResultGenerator.genSuccessResult();
    }

    @Override
    public Result agree(Long userId, Long companionOrderId, Boolean agree) {
        CompanionOrder companionOrder = companionOrderService.findById(companionOrderId);
        CompanionOrderTrack companionOrderTrack = new CompanionOrderTrack();

        if(agree){
            companionOrder.setState(2);
            companionOrderService.update(companionOrder);

            companionOrderTrack.setTrackDesc("同意订单");


        }else{
            companionOrder.setState(5);
            companionOrderService.update(companionOrder);
            CoinTransaction coinTransaction = new CoinTransaction();
            coinTransaction.setOrderId(companionOrder.getOrderId());
            coinTransaction.setAmountBalance(companionOrder.getTotalAmount());
            coinTransaction.setToUserId(companionOrder.getUserId());
            coinTransaction.setTransactionType(6);
            coinTransaction.setRemark("Order rejected");
            coinTransaction.setTransactionTime(new Date().getTime());
            coinTransaction.setCreateId(companionOrder.getUserId());
            coinTransactionService.addOrSub(coinTransaction);
            companionOrderTrack.setTrackDesc("拒绝订单");

        }

        companionOrderTrack.setCreateTime(new Date().getTime());
        companionOrderTrack.setOrderId(companionOrder.getOrderId());
        companionOrderTrack.setUserId(userId);
        companionOrderTrackService.save(companionOrderTrack);

        return ResultGenerator.genSuccessResult();
    }

    @Override
    public Result orderComplete(Long companionOrderId) {
        CompanionOrder companionOrder = companionOrderService.findById(companionOrderId);
        companionOrder.setState(3);
        companionOrderService.update(companionOrder);

        CompanionGame companionGame = companionGameService.findById(companionOrder.getCompanionGameId());
        UserInfo userInfo = userInfoService.findById(companionGame.getCompanionId());

        CoinTransaction coinTransaction = new CoinTransaction();
        coinTransaction.setOrderId(companionOrder.getOrderId());
        coinTransaction.setAmountBalance(companionOrder.getTotalAmount().negate());
        coinTransaction.setToUserId(companionGame.getCompanionId());
        coinTransaction.setFromUserId(userInfo.getUserId());
        coinTransaction.setTransactionType(6);
        coinTransaction.setTransactionTime(new Date().getTime());
        coinTransaction.setRemark("Companion Order Complete");
        coinTransaction.setCreateId(userInfo.getUserId());
        coinTransactionService.addOrSub(coinTransaction);


        CompanionOrderTrack companionOrderTrack = new CompanionOrderTrack();
        companionOrderTrack.setCreateTime(new Date().getTime());
        companionOrderTrack.setOrderId(companionOrder.getOrderId());
        companionOrderTrack.setTrackDesc("完成订单");
        companionOrderTrack.setUserId(companionGame.getCompanionId());
        companionOrderTrackService.save(companionOrderTrack);

        return ResultGenerator.genSuccessResult();
    }

    @Override
    public Result orderReview(Long companionOrderId, String evaluate, BigDecimal score,Long userId) {
        CompanionOrder companionOrder = companionOrderService.findById(companionOrderId);
        if(companionOrder.getState()!=3){
            return ResultGenerator.genFailResult(400,"This order cannot be review");
        }

        companionOrder.setState(4);
        companionOrderMapper.updateByPrimaryKeySelective(companionOrder);


        CompanionReview companionReview = new CompanionReview();
        companionReview.setCompanionOrderId(companionOrderId);
        companionReview.setCreateTime(new Date().getTime());
        companionReview.setEvaluate(evaluate);
        companionReview.setScore(score);
        companionReview.setUserId(userId);

        companionReviewService.save(companionReview);


        CompanionOrderTrack companionOrderTrack = new CompanionOrderTrack();
        companionOrderTrack.setCreateTime(new Date().getTime());
        companionOrderTrack.setOrderId(companionOrder.getOrderId());
        companionOrderTrack.setTrackDesc("评论订单");
        companionOrderTrack.setUserId(companionOrder.getUserId());
        companionOrderTrackService.save(companionOrderTrack);

        return ResultGenerator.genSuccessResult();
    }

    @Override
    public Map<String, Object> detail(Long userId, Long fansId, Boolean service) {

        Map<String, Object> result = new HashMap<>();

        Map<String,Object> userInfo = userInfoMapper.detail(userId);
        result.put("info",userInfo);
        UserFollow follow = userFollowMapper.findByUserIdAndFansId(userId, fansId);
        if(null != follow){
            result.put("follow",true);
        }else{
            result.put("follow",false);
        }
        Map<String,Object> followParams = new HashMap<>();
        followParams.put("userId",userId);
        List<Map<String,Object>> follows = userFollowMapper.listByFollowMe(followParams,new HashMap<String, Object>());
        result.put("followList",follows);
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> orderParams = new HashMap<>();

        params.put("userId",userId);
        orderParams.put(" ","FIELD(cg.examine, 2, 1, 3)");
        params.put("service",service);
        List<ResultMap<String, Object>> res = companionGameMapper.list(params,orderParams );
        for(ResultMap<String, Object> map:res){
            List<DisplayArea> displayAreas = displayAreaService.getByCompanionGameId((Long) map.get("companionGameId"));
            map.put("displayArea",displayAreas);
        }
        result.put("companionGame",res);

        return result;
    }

    @Override
    public Result ban(Long companionId, Boolean ban) {
        Companion companion = findById(companionId);
        companion.setBan( ban);
        update(companion);
        return ResultGenerator.genSuccessResult();
    }
}
